#include "keys.h"



void atualiza_arquivos(pNo_PK *obras, pNo_PK *sk_titulo, pNo_PK *sk_autor, pNo_PK *sk_tipo, pNo_PK *sk_ano, int *tamanho, int *tautor, int *ttitulo, int *ttipo, int *tano) {

	int i = 1, b = 0, atual = 0; 
	int ititulo = 1, iautor = 1 , itipo = 1, iano = 1;
	char * buffer, titulo_aux[tam_titulo+1];
	size_t result;
	long lSize;
	FILE * base, *pk_titulo, *pk_tipo, *pk_autor, *pk_ano;
	
	/* alocacao dos 5 vetores com espaco inicial para 20 registros */

	*obras = malloc((sizeof(No_PK)*20)); 
	*sk_titulo = malloc((sizeof(No_PK)*20)); 
	*sk_tipo = malloc((sizeof(No_PK)*20)); 
	*sk_autor = malloc((sizeof(No_PK)*20)); 
	*sk_ano = malloc((sizeof(No_PK)*20)); 
	base = fopen ("base25.dat","rb");				
	if(base) { 							/* base existe */
		fseek (base, 0 ,SEEK_END);
		lSize = ftell (base);  /*calcula o tamanho total da base */
		rewind (base);			
		buffer = (char*) malloc (sizeof(char)*(tam_titulo+1)); 
		
		/* criacao do vetor que sera gravado no disco como nrr.dat posteriormente. Vetor de indices primarios */
		
		for(i=1;i<=lSize/tam_total;i++) { 
			result = fread (buffer,1,(tam_titulo),base);	/* recebe o titulo e o indice da obra */
			*tamanho = Le_PK(&(*obras),buffer,i,*tamanho,tam_titulo);
			qsort (*obras, *tamanho, sizeof (No_PK), compara);
			fseek (base, (tam_total*i) ,SEEK_SET); 
		}
		
		/* criacao dos arquivos vazios de pk para cada categoria */

		pk_titulo = fopen ("pk_titulo.dat","w");
		pk_tipo = fopen("pk_tipo.dat","w");
		pk_autor = fopen ("pk_autor.dat","w");
		pk_ano = fopen("pk_ano.dat","w");

		/* criacao dos 4 sks (na memoria) em conjunto com os seus respectivos arquivos de pks */ 
		
		for(i=1;i<=lSize/tam_total;i++) { 
			fseek(base, atual, SEEK_SET);
			fread (titulo_aux,1,(tam_titulo),base);
			 
			/* caso o quinto caractere de titulo lido da base seja diferente de * (se tiver * quer dizer que foi removido e por isso nao deve ser adicionado nas nossas chaves) ele fara a adicao desse registro */

			if(titulo_aux[4] != '*') {
				atual = Secondary(&(*sk_titulo), base, pk_titulo , tam_titulo, &ititulo, atual, &(*ttitulo), b); 
				atual = Secondary(&(*sk_tipo), base, pk_tipo , tam_tipo, &itipo, atual, &(*ttipo), b);
				atual = Secondary(&(*sk_autor), base, pk_autor , tam_autor, &iautor, atual, &(*tautor), b);
				atual = Secondary(&(*sk_ano), base, pk_ano, tam_ano, &iano, atual, &(*tano), b); 
				fseek (base, (tam_total*i) ,SEEK_SET);
			}
			b++;
			atual = tam_total*i;
		}
		/* fecha todos os arquivos abertos */

		fclose(base);
		fclose(pk_titulo);
		fclose(pk_tipo);
		fclose(pk_autor);
		fclose(pk_ano);
	}
}


void Writefile(FILE *origem, FILE *destino, int atual) {
	char *nome;

	nome = (char *)malloc(sizeof(char)*(tam_titulo+2)); 
	fseek(origem, atual, SEEK_SET);	 /*coloca o cursor de leitura na posicao atual */
	fgets(nome, tam_titulo+1, origem);
	Fillblanks(nome,tam_titulo); 
	fputs(nome, destino); /* escreve a str nome no arquivo */
	free(nome); /* libera a memoria */
	
}


void Fillblanks(char nome[], int tamanho) {
	int i;
	for (i=(strlen(nome)); i<tamanho; i++) {
		nome[i] = ' ';
	}
	nome[tamanho] = '\0'; /*completa a str com espacos de acordo com o seu tamanho */
}


int Le_PK(pNo_PK *obras, char *titulo, int nrr, int tamanho, int vetor) {
	if ((tamanho % 20 == 0) && (tamanho != 0)) {	 /* realoca memoria caso tamanho maximo seja atingido*/
		*obras = realloc (*obras,(tamanho+tamanho)*sizeof(No_PK)); }

	if(titulo[4] == '*') return tamanho;
	else {
		strcpy((*obras)[tamanho].titulo, titulo); /*insere no vetor obras e adiciona '/0' no fim do titulo*/
		(*obras)[tamanho].nrr = nrr;
		return tamanho+1; /* retorna o novo tamanho */
	}
}


void GravaArray(char string[], int tamanho, pNo_PK obras) {
	int i;
	FILE *teste = fopen ( string , "w" );
	for(i=0;i<tamanho;i++) {
		fputs(obras[i].titulo,teste);  /*grava as infos do vetor sk no disco (sk_*.dat) */ 
		fprintf(teste, "%.4d", obras[i].nrr);
	}
	fclose(teste);
}

void Str_toupper(char *s) { 
while(*s)
	{
		*s=toupper(*s); /* Transforma uma str em maiuscula char por char */
		s++;
	}
}


int Secondary(pNo_PK *obras, FILE *origem, FILE *destino, int tamanhostr,int *indice, int atual, int *tamanho, int contador)  {
	char titulo[tamanhostr+1], aux2 [tamanhostr+1], aux[tamanhostr+1];
	pNo_PK busca;
	size_t result;
	char *p;
	fseek(origem, atual, SEEK_SET);
	result = fread (titulo,1,(tamanhostr),origem);   /* recebe o titulo e o indice da obra*/
	Fillblanks(titulo, tamanhostr);
	strcpy(aux,titulo);
	p = strtok (titulo," ");
	Str_toupper(aux);
	if (p = strtok(NULL, " ")) { /* realiza a verificacao se uma str eh composta, caso seja, adicionara o titulo completo primeiramente */
		if (busca = bsearch (aux, *obras, *tamanho, sizeof (struct No_PK), compara)) { /*caso ja existe no vetor sk */
			Writefile(origem, destino, contador*tam_total); /*escreve somente no arquivo com o indice atualizado */
			fprintf(destino, "%.4d", busca->nrr);
			busca->nrr = *indice; /*atualiza o vetor */ 
		}
		else { /* caso ainda nao exista */
			*tamanho = Le_PK(&(*obras),aux, *indice, *tamanho, tamanhostr); 
			Writefile(origem, destino, contador*tam_total); /* adiciona tanto no vetor como no arquivo com indice -001 */
			fputs("-001",destino); 
		}
		*indice = *indice + 1; 
	}
	p = strtok(aux," "); 
	strcpy(aux2,p);
	Str_toupper(aux2);
	Fillblanks(aux2, tamanhostr);
	while (p) { /*adicao do titulo quebrado em pedacos (strtok) ate chegar ao final (NULL) */
		if (busca = bsearch (aux2, *obras, *tamanho, sizeof (struct No_PK), compara)) {
			Writefile(origem, destino, contador*tam_total); /* !!Similar acima, apenas com a str quebrada!! */
			fprintf(destino, "%.4d", busca->nrr);
			busca->nrr = *indice;
		}
		else {
			*tamanho = Le_PK(&(*obras),aux2, *indice, *tamanho, tamanhostr);
			Writefile(origem, destino, contador*tam_total);
			fputs("-001",destino); 				/* !!Similar acima, apenas com a str quebrada!! */
		}
		*indice = *indice + 1; 
		if (p = strtok (NULL," ")) {
			strcpy(aux2,p);		/* quebra novamente e mantem o while ate null */
			Str_toupper(aux2);
			Fillblanks(aux2, tamanhostr);
		}
	}
	qsort (*obras, *tamanho, sizeof (No_PK), compara); /* usa o qsort para ordenar o vetor atualizado em ordem alfabetica */
	atual += tamanhostr;
	return atual;/*atualiza a posicao atual */

}
